#include "hal_esp8266.h"
#include "gd32vf103c_start.h"

struct STRUCT_USART_Fram_S Esp8266_Frame_Record;

/**
  * @brief  初始化ESP8266用到的GPIO引脚
  * @param  无
  * @retval 无
  */
void hal_esp8266_gpio_init ( void )
{
	/* 配置 CH_PD 引脚*/
    rcu_periph_clock_enable(ESP8266_CH_PD_CLK);

	gpio_init(ESP8266_CH_PD_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, ESP8266_CH_PD_PIN);


	/* 配置 RST 引脚*/
    rcu_periph_clock_enable(ESP8266_RST_CLK);

	gpio_init(ESP8266_RST_PORT, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, ESP8266_RST_PIN);
}


/**
  * @brief  初始化ESP8266用到的 USART
  * @param  无
  * @retval 无
  */
void hal_esp8266_uart_init ( void )
{
	gd_eval_com_init(EVAL_COM2);
}

void hal_esp8266_delayms ( int ms )
{
	rt_thread_mdelay(ms);
}


/*
 * 函数名：itoa
 * 描述  ：将整形数据转换成字符串
 * 输入  ：-radix =10 表示10进制，其他结果为0
 *         -value 要转换的整形数
 *         -buf 转换后的字符串
 *         -radix = 10
 * 输出  ：无
 * 返回  ：无
 * 调用  ：被USART2_printf()调用
 */
static char * itoa( int value, char *string, int radix )
{
	int     i, d;
	int     flag = 0;
	char    *ptr = string;

	/* This implementation only works for decimal numbers. */
	if (radix != 10)
	{
		*ptr = 0;
		return string;
	}

	if (!value)
	{
		*ptr++ = 0x30;
		*ptr = 0;
		return string;
	}

	/* if this is a negative value insert the minus sign. */
	if (value < 0)
	{
		*ptr++ = '-';

		/* Make the value positive. */
		value *= -1;

	}

	for (i = 10000; i > 0; i /= 10)
	{
		d = value / i;

		if (d || flag)
		{
			*ptr++ = (char)(d + 0x30);
			value -= (d * i);
			flag = 1;
		}
	}

	/* Null terminate the string. */
	*ptr = 0;

	return string;

} /* NCL_Itoa */



/*
 * 函数名：USART_printf
 * 描述  ：格式化输出，类似于C库中的printf，但这里没有用到C库
 * 输入  ：-USARTx 串口通道，
 *		     -Data   要发送到串口的内容的指针
 *			   -...    其他参数
 * 输出  ：无
 * 返回  ：无
 * 调用  ：外部调用
 *         典型应用USART2_printf( USART2, "\r\n this is a demo \r\n" );
 *            		 USART2_printf( USART2, "\r\n %d \r\n", i );
 *            		 USART2_printf( USART2, "\r\n %s \r\n", j );
 */
void hal_esp8266_printf ( char * Data, ... )
{
	const char *s;
	int d;
	char buf[16];


	va_list ap;
	va_start(ap, Data);

	while ( * Data != 0 )     // 判断是否到达字符串结束符
	{
		if ( * Data == 0x5c )  //'\'
		{
			switch ( *++Data )
			{
				case 'r':							          //回车符
				usart_data_transmit(EVAL_COM2, 0x0d);
				Data ++;
				break;

				case 'n':							          //换行符
				usart_data_transmit(EVAL_COM2, 0x0a);
				Data ++;
				break;

				default:
				Data ++;
				break;
			}
		}

		else if ( * Data == '%')
		{									  //
			switch ( *++Data )
			{
				case 's':										  //字符串
				s = va_arg(ap, const char *);

				for ( ; *s; s++)
				{
					usart_data_transmit(EVAL_COM2,*s);
					while ( usart_flag_get(EVAL_COM2, USART_FLAG_TBE)== RESET);
				}

				Data++;

				break;

				case 'd':
					//十进制
				d = va_arg(ap, int);

				itoa(d, buf, 10);

				for (s = buf; *s; s++)
				{
					usart_data_transmit(EVAL_COM2,*s);
					while ( usart_flag_get(EVAL_COM2, USART_FLAG_TBE)== RESET);
				}

				Data++;

				break;

				default:
				Data++;

				break;

			}
		}

		else usart_data_transmit(EVAL_COM2, *Data++);

		while ( usart_flag_get(EVAL_COM2, USART_FLAG_TBE)== RESET);

	}
}

volatile uint32_t cnt = 0;

void USART2_IRQHandler()
{
	uint8_t ch = -1;

    if(RESET != usart_interrupt_flag_get(EVAL_COM2, USART_INT_FLAG_RBNE))
    {
		ch =  usart_data_receive(EVAL_COM2);
//		if ( Esp8266_Frame_Record.FramLength < ( RX_BUF_MAX_LEN - 1 ) )                       //预留1个字节写结束符
//		{
			Esp8266_Frame_Record .Data_RX_BUF [ Esp8266_Frame_Record.FramLength ]  = ch;
//		}
		Esp8266_Frame_Record.FramLength ++;
		if (Esp8266_Frame_Record.FramLength >= 1024)
		{
			Esp8266_Frame_Record.FramLength = 0;
		}
		cnt = Esp8266_Frame_Record.FramLength;
//		rt_kprintf(".......uart recv : %c, count is %d\r\n", ch, cnt);
		Esp8266_Frame_Record.InfBit.FramStartFlag = 1;
    }
}

